package com.xyzk.diagnose.httputils;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;

import com.xyzk.diagnose.tools.Common;
import com.xyzk.diagnose.tools.Commonfunc;

import android.util.Log;

public class ServerSocket{
	private final static String TAG = "ServerSocket";
	private static Socket socket;
	private static DataOutputStream dout;
	private static DataInputStream  din;

	/**
	 * 建立socket连接
	 * @param ip 服务器IP
	 * @param port 端口
	 * @return
	 */
	public boolean connectServer(String ip,int port){
		try {
			socket = new Socket();
			SocketAddress addr = new InetSocketAddress(ip, port);
			socket.connect(addr, Common.SERVER_MAX_TIME);
			dout = new DataOutputStream(socket.getOutputStream());
			din  = new DataInputStream (socket.getInputStream());
			Commonfunc.sleep(50);//实际中刚连上后发数据需要一定延时  确保双方链接初始化完成
			if(Common.DEBUG) Log.i(TAG,"Socket连接成功!");
		} catch (UnknownHostException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 根据VIN码从上位机获取配置
	 * @param Pvin VIN码
	 * @param Readbuf 接收字节数组
	 * @return  字节长度
	 */
	public int searchPinFromConfig(String Pvin, byte [] Readbuf){
		int len = 0;
		if(dout == null || din == null) return 0; //未连接
		try {
			if(din.available() > 0){  //先清除数据
				byte[] Precv = new byte[din.available()];
				din.read(Precv, 0, din.available());
			}
			dout.write(Commonfunc.getByteLenOfFive("2:" + Pvin).getBytes());
			dout.flush();
			if(Common.DEBUG) Log.i(TAG,"Send:" + "2:" + Pvin);
		} catch (IOException e) {
			e.printStackTrace();
		}
		len = receiveData(Common.SERVER_MAX_TIME, Readbuf, Readbuf.length);
		return len > 3 ? len : 0;
	}

	/**
	 * 根据VIN码从上位机获取TPMS id
	 * @param Pvin VIN码
	 * @param Readbuf 接收字节数组
	 * @param Psize 接收字节数组长度
	 * @return  字节长度
	 */
	public int searchVinFromTpmsDb(String Pvin, byte [] Readbuf){
		int len = 0;
		if(dout == null || din == null) return 0; //未连接
		try {
			if(din.available() > 0){  //先清除数据
				byte[] Precv = new byte[din.available()];
				din.read(Precv, 0, din.available());
			}
			dout.write(Commonfunc.getByteLenOfFive("4:" + Pvin).getBytes());
			dout.flush();
			if(Common.DEBUG) Log.i(TAG,"Send:" + "4:" + Pvin);
		} catch (IOException e) {
			e.printStackTrace();
		}
		len = receiveData(Common.SERVER_MAX_TIME, Readbuf, Readbuf.length);
		return len > 10 ? len : 0;
	}

	/**
	 * 数据上传工控机/服务器
	 * @param Pdata上传数据
	 * @return 是否上传成功
	 */
	public boolean sendDataToServer(String Pdata){
		if(dout == null || din == null) return false;
		try {
			if(din.available() > 0){//先清除数据
				din.read(new byte[din.available()], 0, din.available());
			}
			dout.write(Pdata.getBytes());
			dout.flush();
			if(Common.DEBUG) Log.i(TAG,"Send:" + Pdata);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return receiveData(Common.SET_MAX_TIME)> 0 ? true : false;
	}

	public int sendDataToServer(String Pdata,byte [] Pbuf)
	{
		int len = 0;
		if(dout == null || din == null) return len; //未连接
		try {
			if(din.available() > 0)  //先清除数据
			{
				byte[] Precv = new byte[din.available()];
				din.read(Precv, 0, din.available());
			}
			//dout.write(Pdata.length());
			dout.write(Pdata.getBytes());
			dout.flush();
			if(Common.DEBUG) Log.i(TAG,"Send:" + Pdata);
		} catch (IOException e) {
			e.printStackTrace();
		}
		len = receiveData(Common.SERVER_MAX_TIME,Pbuf,Pbuf.length);
		return len;
	}
	/**
	 * 接收数据
	 * @param maxtime 超时时间
	 * @return 接收数据长度
	 */
	private int receiveData(int maxtime){
		int len = 0;
		if(dout == null || din == null){
			if(Common.DEBUG) Log.e(TAG,"ReceiveData exit 1"); return -1;
		}
		try {
			long starttime = System.currentTimeMillis();//获得起始时间
			long endtime = 0;
			while(true){
				if(dout == null || din == null){
					if(Common.DEBUG) Log.e(TAG,"ReceiveData exit 2");break;
				}
				len = din.available();
				if(len > 0){
					byte[] Precv = new byte[len];
					din.read(Precv,0,len);
					if(Common.DEBUG) Log.i(TAG,"ReceiveData:" + new String(Precv));
					break;
				}
				endtime = System.currentTimeMillis();
				if((endtime - starttime) > maxtime){ //超时
					if(Common.DEBUG) Log.i(TAG,"超时退出!");
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		Commonfunc.sleep(Common.SET_WAIT_TIME);
		return len;
	}

	/**
	 * 接收数据
	 * @param maxtime 超时时间
	 * @param Pbuf   接收字节数组
	 * @param Psize 接收字节数组大小
	 * @return 接收数据长度
	 */
	private int receiveData(int maxtime, byte [] Pbuf, int Psize){
		int len = 0;
		if(dout == null || din == null){
			if(Common.DEBUG) Log.e(TAG,"ReceiveData exit 1"); return -1;
		}
		try {
			long starttime = System.currentTimeMillis(); //获得起始时间
			long endtime = 0;
			while(true){
				if(dout == null || din == null) {
					if(Common.DEBUG) Log.e(TAG,"ReceiveData exit 2");break;
				}
				len = din.available();
				if(len > 0)	{
					byte[] Precv = new byte[len];
					din.read(Precv,0,len);
					if(len > Psize){
						System.arraycopy(Precv, 0, Pbuf, 0, Psize);
					}else
						System.arraycopy(Precv, 0, Pbuf, 0, len);
					if(Common.DEBUG) Log.i(TAG,"ReceiveData:" + new String(Precv));
					break;
				}
				endtime = System.currentTimeMillis();
				if((endtime - starttime) > maxtime){//超时
					if(Common.DEBUG) Log.i(TAG,"超时退出!");
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		Commonfunc.sleep(Common.SET_WAIT_TIME);
		return len;
	}

	/**
	 * 关闭Socket连接
	 */
	public void close(){
		try {
			if(dout != null){
				dout.close();
				dout = null;
			}
			if(din != null){
				din.close();
				din = null;
			}
			if(socket != null){
				socket.close();
				socket = null;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
